package com.shinbada.modules.competitor.service;

import com.shinbada.excel.ExcelKit;
import com.shinbada.excel.handler.DefaultExcelReadStrategyHandlerV3;
import com.shinbada.excel.modle.CheckResult;
import com.shinbada.excel.modle.ImportExcelResult;
import com.shinbada.excel.modle.StrategyCheckService;
import com.shinbada.excel.modle.UploadModle;

import java.util.List;

import com.google.common.collect.Maps;
import java.util.Map;
import java.util.stream.Collectors;

import com.shinbada.modules.competitor.entity.CompetitorParamEncylopedia;
import com.shinbada.modules.competitor.entity.VO.CompetitorProductDataItemVO;
import lombok.SneakyThrows;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.shinbada.core.persistence.Page;
import com.shinbada.core.service.CrudService;
import com.shinbada.modules.competitor.entity.CompetitorProductDataItem;
import com.shinbada.modules.competitor.mapper.CompetitorProductDataItemMapper;
import org.springframework.web.multipart.MultipartFile;

/**
 * 产品数据项Service
 * @author initcap
 * @version 2021-08-04
 */
@Service
@Transactional(readOnly = true)
public class CompetitorProductDataItemService extends CrudService<CompetitorProductDataItemMapper, CompetitorProductDataItem> implements StrategyCheckService<CompetitorProductDataItem> {

	@Autowired
	private CompetitorParamEncylopediaService competitorParamEncylopediaService;

    private Map<String, String> keys;

	private Map<String, String> competitorParamEncylopediaMap;

	@Override
	public CompetitorProductDataItem get(String id) {
		return super.get(id);
	}

	@Override
	public List<CompetitorProductDataItem> findList(CompetitorProductDataItem competitorProductDataItem) {
		return super.findList(competitorProductDataItem);
	}

	@Override
	public Page<CompetitorProductDataItem> findPage(Page<CompetitorProductDataItem> page, CompetitorProductDataItem competitorProductDataItem) {
		return super.findPage(page, competitorProductDataItem);
	}

	@Transactional(readOnly = false)
	@Override
	public void save(CompetitorProductDataItem competitorProductDataItem) {
		super.save(competitorProductDataItem);
	}

	@Transactional(readOnly = false)
	@Override
	public void delete(CompetitorProductDataItem competitorProductDataItem) {
		super.delete(competitorProductDataItem);
	}

	@Transactional(readOnly = false)
	@SneakyThrows
    public ImportExcelResult<CompetitorProductDataItem> uploadExcel(MultipartFile file, UploadModle modle) {
		// 1. 准备提前数据
		readExcelInit();
		// 2. 添加数据处理器
		DefaultExcelReadStrategyHandlerV3<CompetitorProductDataItem> excelReadHandler = new DefaultExcelReadStrategyHandlerV3<>(modle, this);
		// 3. 执行导入
		ExcelKit.$Import(CompetitorProductDataItem.class).readXlsx(file.getInputStream(), excelReadHandler);
		// 4. 获得导入结果集
		ImportExcelResult<CompetitorProductDataItem> importExcelResult = excelReadHandler.results();
		// 5. 批量添加成功数据
		importExcelResult.getSuccessList().forEach(this::save);
		// 返回结果,成功的数据不返回了，影响响应速度
		importExcelResult.setSuccessList(null);
		return importExcelResult;

    }

    /**
     * @param entity 实体类
     * @return 这个key的获取决定了，在Excel导入的时候需要校验的唯一标准
     */
    private String getReadExcelKey(CompetitorProductDataItem entity) {
        return entity.getId() + entity.getRemarks();
    }

	private void readExcelInit() {
    	// 获取到现在数据库中的所有数据
    	List<CompetitorProductDataItem> db = mapper.findAllList(new CompetitorProductDataItem());
    	this.keys = Maps.newHashMapWithExpectedSize(db.size());
		// 转换键配置,请根据必要条件实现，直接使用会有问题
        db.forEach(entity -> this.keys.put(getReadExcelKey(entity), entity.getId()));
	}

	@Override
	public CheckResult readAndCheck(CompetitorProductDataItem entity) {
    	// 验证重复数据,请根据必要条件实现，直接使用会有问题
    	String key = getReadExcelKey(entity);
		if (this.keys.containsKey(key)) {
			entity.setId(this.keys.get(key));
			return CheckResult.cover(key);
		}
		// 添加数据
		this.keys.put(key, "");
		return CheckResult.pass(key);
	}

	/**
	 * 根据类型获取数据项实体
	 * @param type
	 * @return
	 */
	public List<CompetitorProductDataItem> selectDataItemByType(String type) {

		return mapper.selectDataItemByType(type);
	}

	/**
	 * 根据数据类型 获取对应的数据项树
	 *
	 * @param parameterType
	 * @param dataItemType
	 * @return
	 */
	public List<CompetitorProductDataItemVO> getTreeStructure(String dataItemType,String parameterType) {

		List<CompetitorProductDataItemVO> competitorProductDataItemList = mapper.getTreeStructure(dataItemType,parameterType);
		if (CollectionUtils.isNotEmpty(competitorProductDataItemList)) {
			checkIsNotSkip(competitorProductDataItemList);
		}
		return competitorProductDataItemList;
	}

	/**
	 * 检查是否可以跳转链接
	 * @param competitorProductDataItemList
	 */
	private void checkIsNotSkip(List<CompetitorProductDataItemVO> competitorProductDataItemList) {
		List<CompetitorParamEncylopedia> allList = competitorParamEncylopediaService.findAllList(new CompetitorParamEncylopedia());
		this.competitorParamEncylopediaMap  = allList.stream().collect(Collectors.toMap(CompetitorParamEncylopedia::getName, CompetitorParamEncylopedia::getId));
		competitorProductDataItemList.stream().forEach(competitorProductDataItemVO -> {
			String dataItemName = this.competitorParamEncylopediaMap.get(competitorProductDataItemVO.getDataItemName());
			if (dataItemName != null && dataItemName != "") {
				competitorProductDataItemVO.setSkip(1);
			}
		});
	}

	public List<CompetitorProductDataItemVO> getDisaffinityDataItem(String[] array, String dataItemType, String parameterType) {
		return mapper.getDisaffinityDataItem(array,dataItemType,parameterType );
	}
}
